﻿using Castle.DynamicProxy;
using Microsoft.Extensions.Logging;
using System.Text.Json;

namespace HelperCommon.AOP
{
    public class LogAOP : IInterceptor
    {
        protected readonly ILogger<LogAOP> Nlog;

        /// <summary>
        /// 采用Nlog记录日志,同样使用构造函数注入Nlog
        /// </summary>
        /// <param name="logger"></param>
        public LogAOP(ILogger<LogAOP> logger)
        {
            Nlog = logger;
        }

        /// <summary>
        /// 实现继承IInterceptor的方法
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            //记录日志的String,在请求接口的时候会先进行拦截，可以获取到方法的名称,方法在哪个位置，所带参数等
            var dataIntercept = "\n\t" +
                 $"【当前执行方法:{invocation.Method.Name}】\n\t" +
                 $"【携带的参数有:{string.Join(",", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())}】\n\t" +
                 $"【当前执行方法的位置:{invocation.InvocationTarget}】\n\t";

            try
            {
                //这个Proceed是执行这个方法，不写的话就204，不会处理该请求
                invocation.Proceed();
                //如果Proceed成功执行，则返回到请求的结果
                dataIntercept += ($"【执行完成结果：】{JsonSerializer.Serialize(invocation.ReturnValue)}");
            }
            catch (Exception e)
            {
                //如果Proceed里面异常了，就会在此处获取到异常信息。
                dataIntercept += ($"【方法异常：】{e.Message + e.InnerException}");
            }
            //为了在日志里划分区域范围，容易查看
            dataIntercept += ("\n\n=======================================================================");
            //这个地方目前我不知道怎么解释，但是记录日志要写在里面
            Parallel.For(0, 1, e =>
            {
                Nlog.LogInformation(dataIntercept);
            });
        }
    }
}